package com.xianggu.mybatis.mysql;

import com.alibaba.druid.pool.DruidDataSource;
import com.xianggu.mybatis.configFile.FileReaderContext;
import com.xianggu.mybatis.configFile.FileReaderStrategy;
import com.xianggu.mybatis.configFile.PropertyReader;
import com.xianggu.mybatis.configFile.YamlParser;
import com.xianggu.mybatis.enums.MysqlConnectParam;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DruidExample {
    private static DruidDataSource dataSource;

    static {
        String driverClassName = "";
        // 用策略模式配置读取文件顺序
        List<FileReaderStrategy> strategies = new ArrayList<>();
        strategies.add(new YamlParser());
        strategies.add(new PropertyReader());

        MysqlConnectParam connectParam = null;

        FileReaderContext context = new FileReaderContext(strategies);
        try {
            // 策略入口
            connectParam = context.readFile();
            if(connectParam != null ){
                // 读取用户信息
                driverClassName = connectParam.getDriverClassName();
            }else{
                throw new RuntimeException("读取数据库配置文件失败，请检查配置！");
            }

        } catch (IOException e) {
            throw new RuntimeException("读取数据库异常："+e);
        }

        // 加载驱动
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        if(connectParam == null){
            throw new RuntimeException("读取数据库配置文件失败，请检查配置！");
        }

        // 初始化 Druid 连接池
        dataSource = new DruidDataSource();

        // 基本配置
        dataSource.setUrl(connectParam.getUrl());
        dataSource.setUsername(connectParam.getUsername());
        dataSource.setPassword(connectParam.getPassword());

        // 连接池参数
        dataSource.setInitialSize(connectParam.getInitialSize());                     // 初始化连接数
        dataSource.setMinIdle(connectParam.getMinIdle());                         // 最小空闲连接数
        dataSource.setMaxActive(connectParam.getMaxActive());                     // 最大连接数
        dataSource.setMaxWait(connectParam.getMaxWait());                     // 获取连接的最大等待时间（毫秒）
        dataSource.setTimeBetweenEvictionRunsMillis(connectParam.getTimeBetweenEvictionRunsMillis()); // 检测空闲连接的间隔时间（毫秒）
        dataSource.setMinEvictableIdleTimeMillis(connectParam.getMinEvictableIdleTimeMillis());  // 连接的最小空闲时间（毫秒）
        dataSource.setValidationQuery("SELECT 1 FROM DUAL"); // 连接有效性检查的 SQL
        dataSource.setTestWhileIdle(connectParam.isTestWhileIdle());                // 空闲时是否检查连接有效性
        dataSource.setTestOnBorrow(connectParam.isTestOnBorrow());                // 获取连接时是否检查有效性
        dataSource.setTestOnReturn(connectParam.isTestOnReturn());               // 归还连接时是否检查有效性
        dataSource.setPoolPreparedStatements(connectParam.isPoolPreparedStatements());       // 是否缓存 PreparedStatement
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(connectParam.getMaxPoolPreparedStatementPerConnectionSize()); // 每个连接上缓存的 PreparedStatement 数量

        // 监控和日志过滤器
//        try {
//            dataSource.setFilters("stat,slf4j");
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }

        // 连接属性
        dataSource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");
    }

    /**
     * 从连接池获取连接
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void main(String[] args) {
        try (Connection connection = getConnection()) {
            System.out.println("成功获取连接: " + connection);
            // 执行 SQL 操作
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接池
            dataSource.close();
        }
    }
}